package com.kindness.frate.widget;

import android.animation.ValueAnimator;
import android.content.Context;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;

import com.kindness.frate.R;
import com.kindness.frate.animate.AnimateUtils;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

/**
 * 阿里支付首页Behavior
 */
public class AliPayBehavior extends CoordinatorLayout.Behavior {

    private WeakReference<View> dependentView;
    private WeakReference<View> childeView;
    private WeakReference<View> llBehaviorBack;
    private int heardSize = -1;
    private int minHeard = -1;
    int newState = -10;
    private ValueAnimator animator;
    private List<Integer> datas = new ArrayList<>();
    private boolean isScroll;

    public AliPayBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
        if (child != null) {
            childeView = new WeakReference<View>(child);
            if (childeView.get() instanceof RecyclerView) {
                RecyclerView recyclerView = (RecyclerView) childeView.get();
                recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {

                    @Override
                    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                        super.onScrollStateChanged(recyclerView, newState);
                        AliPayBehavior.this.newState = newState;
                        if (datas.size() < 2) {
                            return;
                        }
                        if (recyclerView.getTranslationY() <= minHeard && !recyclerView.canScrollVertically(-1) && newState == RecyclerView.SCROLL_STATE_IDLE && datas.get(datas.size() - 2) < 0) {
                            int dy = Math.abs(datas.get(datas.size() - 2));
                            dy = dy > heardSize ? heardSize : (minHeard + dy) > heardSize ? heardSize : minHeard + dy;
                            float value = Math.abs(dy) * 1.f / (heardSize - minHeard);
                            if (value >= 0)
                                creatExpendAnimator(minHeard, Math.abs(dy), (int) Math.abs((1.f - value) * 300));
                            int start = minHeard;
                            int end = Math.abs(dy);
                            int duration = (int) Math.abs((1.f - value) * 300);
                            final int position = dy;
                            new AnimateUtils().valueAnimateChange(start, end, duration, animation -> {
                                float progress = (float) animation.getAnimatedValue();
                                View view = dependentView.get();
                                ViewGroup.LayoutParams params = view.getLayoutParams();
                                params.height = (int) progress;
                                view.setLayoutParams(params);
                                childeView.get().setTranslationY(progress);
                                llBehaviorBack.get().setTranslationY((progress - heardSize) * 0.5f);
                                if (progress == position) {
                                    float local = position;
                                    if (local < 0.5f * heardSize) {
                                        float content = (local - minHeard) * 1.f / (heardSize - minHeard);
                                        creatExpendAnimator(local, minHeard, (int) (500 * content));
                                    } else {
                                        float content = (heardSize - local) * 1.f / (heardSize - minHeard);
                                        creatExpendAnimator(local, heardSize, (int) (500 * content));
                                    }
                                    datas.clear();
                                }
                            });
                        }
                    }

                    @Override
                    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                        super.onScrolled(recyclerView, dx, dy);
                        datas.add(dy);
                    }
                });
            }
        }
        if (dependency != null && dependency instanceof RelativeLayout) {
            dependentView = new WeakReference<>(dependency);
            llBehaviorBack = new WeakReference<View>(dependency.findViewById(R.id.ll_behavior_back));
            return true;
        }
        return super.layoutDependsOn(parent, child, dependency);
    }

    @Override
    public boolean onLayoutChild(CoordinatorLayout parent, View child, int layoutDirection) {
        child.layout(0, 0, parent.getWidth(), (parent.getHeight() - dependentView.get().getHeight()));
        if (heardSize == -1) {
            heardSize = dependentView.get().getHeight();
            minHeard = dependentView.get().findViewById(R.id.ll_behavior_title).getHeight();
            child.setTranslationY(heardSize);
        }
        return true;
    }

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
        float translationY = child.getTranslationY();
        float min = minHeard * 1.0f / heardSize;
        float pro = translationY / heardSize;
        View child1 = dependency.findViewById(R.id.ll_behavior_back);
        View titleView = dependentView.get().findViewById(R.id.ll_behavior_title);
        titleView.setAlpha(1 - pro);
        if (pro <= min + 0.1) {
            titleView.setAlpha(1);
        }
        if (pro > 0.95) {
            titleView.setVisibility(View.GONE);
        } else {
            titleView.setVisibility(View.VISIBLE);
        }
        if (pro >= min && pro <= 1) {
            child1.setAlpha(pro);
            if (pro < 0.5) {
                child1.setVisibility(View.GONE);
            } else {
                child1.setVisibility(View.VISIBLE);
            }
            return true;
        }
        return super.onDependentViewChanged(parent, child, dependency);
    }

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
        return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL;
    }

    @Override
    public void onNestedScrollAccepted(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
        clearAnimotor();
        isScroll = false;
    }

    @Override
    public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) {
        View view = dependentView.get();
        ViewGroup.LayoutParams params = view.getLayoutParams();
        int height = (int) child.getTranslationY();
        if (dy > 0 && height > minHeard) {
            if (height <= heardSize) {
                int h = height - dy;
                int H = (h < minHeard) ? minHeard : h;
                params.height = H;
                view.setLayoutParams(params);
                child.setTranslationY(H);
                llBehaviorBack.get().setTranslationY((H - heardSize) * 0.5f);
                consumed[1] = dy;
            }
        }
    }

    @Override
    public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
        if (dyUnconsumed > 0) {
            return;
        }
        View view = dependentView.get();
        ViewGroup.LayoutParams params = view.getLayoutParams();
        int height = (int) child.getTranslationY();
        if (dyUnconsumed < 0 && params != null) {
            int h = height - dyUnconsumed;
            if (h >= 0 && h <= heardSize) {
                params.height = h;
                view.setLayoutParams(params);
                child.setTranslationY(h);
                llBehaviorBack.get().setTranslationY((h - heardSize) * 0.5f);
            }
        }
    }

    @Override
    public boolean onNestedFling(CoordinatorLayout coordinatorLayout, View child, View target, float velocityX, float velocityY, boolean consumed) {
        return false;
    }

    @Override
    public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target) {
        int height = dependentView.get().getHeight();
        childeView.get().setScrollY(0);
        // 上滑
        if (height <= 0.7 * heardSize) {
            float value = (height - minHeard) * 1.f / (heardSize - minHeard);
            creatExpendAnimator(height, minHeard, (int) (500 * value));
        } else {
            float value = (heardSize - height) * 1.f / (heardSize - minHeard);
            creatExpendAnimator(height, heardSize, (int) (500 * value));
        }
        if (! isScroll&& height > minHeard && height < heardSize) {
            childeView.get().setScrollY(0);
            if (height < 0.7 * heardSize) {//上滑
                float pro = (height - minHeard) * 1.0f / (heardSize - minHeard);
                creatAnimation(height, minHeard, (int) (500 * pro));
            } else {//下滑
                float pro = (heardSize - height) * 1.0f / (heardSize - minHeard);
                creatAnimation(height, heardSize, (int) (500 * pro));
            }
            isScroll = true;
        }
    }

    private void creatAnimation(float start, float end, int duration) {
        clearAnimotor();
        animator = ValueAnimator.ofFloat(start, end);
        animator.addUpdateListener(animation -> {
            float value = (float) animation.getAnimatedValue();
            View view = dependentView.get();
            ViewGroup.LayoutParams params = view.getLayoutParams();
            params.height = (int) value;
            view.setLayoutParams(params);
            childeView.get().setTranslationY(value);
        });
        animator.setDuration(duration);
        animator.start();
    }

    private void clearAnimotor() {
        if (animator != null) {
            animator.cancel();
        }
        isScroll = false;
    }

    @Override
    public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, View child, View target, float velocityX, float velocityY) {
        return onStopDrag(child, velocityY);
    }

    private boolean onStopDrag(View child, float velocityY) {
        int height = dependentView.get().getHeight();
        if (height > minHeard) {
            return true;
        } else {
            return false;
        }
    }

    private void creatExpendAnimator(float start, float end, int duration) {
        clearAnimotor();
        animator = new AnimateUtils().valueAnimateChange(start, end, duration, animation -> {
            float value = (float) animation.getAnimatedValue();
            View view = dependentView.get();
            ViewGroup.LayoutParams params = view.getLayoutParams();
            params.height = (int) value;
            view.setLayoutParams(params);
            childeView.get().setTranslationY(value);
            llBehaviorBack.get().setTranslationY((value - heardSize) * 0.5f);
        });
    }

}